using System;
using System.Threading;
using MCSharp;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;

namespace    ctem.kernel.logger
{
 using System;
using MCSharp;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;

[Serializable()]
public  partial class MainLogger:ILoggingManagment, ISerializable {

 //-------------- MCsharp functions -----------

 public MainLogger ( ) {
  mcsharp_initiate();
}

 public MainLogger ( SerializationInfo info, StreamingContext context ) {
  MCSharp.Serialization.UnPack ( info, context, this );
   }

 public void GetObjectData ( SerializationInfo info, StreamingContext context ) {
  MCSharp.Serialization.Pack ( info, context, this );
 }

 public void mcsharp_initiate ( ) {

  Monitor.Enter ( CommExec.Objects );
  int mcObjectNumber = CommExec.Objects.Count + 1;
  CommExec.Objects.Add ( mcObjectNumber, this );
  Monitor.Exit ( CommExec.Objects );

  AddChannel = new MCSharp.channel ( this, mcObjectNumber, "mcsharpChannelAddChannel" );
 }

internal  void Add (  LogEvent log_event )   {
   AddChannel.Send ( new object[] {  log_event   } )
  ;
 }

 //-------------Channel declarations-----------------

  public MCSharp.channel AddChannel;

 //-------------Masks--------------------------------

 private const int mcsharp_mask_AddChannel = 1 << 0;
 [NonSerialized] private MCSharp.BitMask mcsharpBitMaskAddChannel = new MCSharp.BitMask();

 private void scanAddChannel () {
  if ( mcsharpBitMaskAddChannel.match
        ( mcsharp_mask_AddChannel ) )
  {   Monitor.Enter ( AddChannel );
   object[] oAddChannel = (object[]) AddChannel.Dequeue();
   LogEvent log_event = (LogEvent) oAddChannel [0];
   if ( AddChannel.Count == 0 )
       mcsharpBitMaskAddChannel.clear ( mcsharp_mask_AddChannel );
   Monitor.Exit ( AddChannel );
   McsharpPrivateClassAddChannel prclassobject = new McsharpPrivateClassAddChannel ( this , log_event );
   ThreadStart tstart = new ThreadStart ( prclassobject.run );
   ( new Thread ( tstart ) ).Start();
   scanAddChannel();
  }
}


[OneWay]
public void mcsharpChannelAddChannel (  LogEvent log_event )  {
   lock ( AddChannel ) {
    AddChannel.Enqueue ( new object [] { log_event } );
    if ( ! mcsharpBitMaskAddChannel.match
          ( mcsharp_mask_AddChannel ) )   {
     mcsharpBitMaskAddChannel.set ( mcsharp_mask_AddChannel );
     scanAddChannel ();
    }
   }
 }

  private class McsharpPrivateClassAddChannel {

   MainLogger parent;
   LogEvent log_event;

   public McsharpPrivateClassAddChannel ( MainLogger parent,
               LogEvent log_event
              ) {
    this.parent = parent;
    this.log_event = log_event;
   }

   public void run() {

   MCSharp.ThreadManager.SetThreadAffinityMask();

    parent.mcsharpAddChannelBody ( log_event );

   }
  }

  private void mcsharpAddChannelBody (
               LogEvent log_event
              )
 {
   try {
    Monitor.Enter( buffer  )  ;
 log_event.n  = buffer.Count + 1  ;
 buffer.Add( log_event  )  ;
 if ( config.LogToWindowsConsole   )
    {
   console.WriteTo( log_event  )  ;
 }

     }
   finally {
    Monitor.Exit( buffer  )  ;
   }
  
   }


}


}